/*
 * Galaxium Messenger
 * Copyright (C) 2007-2008 Ben Motmans <ben.motmans@gmail.com>
 * Copyright (C) 2007 Philippe Durand <draekz@gmail.com>
 * Copyright (C) 2007 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;

using Gdk;
using Gtk;
using Glade;

using Galaxium.Core;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;
using Galaxium.Protocol;

using Anculus.Core;

namespace Galaxium.Client.GtkGui
{
	public class SoundPreferenceWidget: IPreferenceWidget<Widget>
	{
		[Widget("vbSets")] VBox _vbSets;
		[Widget("btnPlay")] ToolButton _btnPlay;
		[Widget("tvSounds")] TreeView _tvSounds;
		[Widget("lblAuthor")] Label _lblAuthor;
		[Widget("lblDescription")] Label _lblDescription;
		[Widget("buttonSelectAll")] Button _btnSelectAll;
		[Widget("buttonSelectNone")] Button _btnSelectNone;
		
		Widget _nativeWidget;
		ImageComboBox<ISoundSet> _cbSets;
		ISoundSet _noneSet;
		ListStore _store;
		
		public void Initialize ()
		{
			_nativeWidget = GladeUtility.ExtractWidget<Widget> (GladeUtility.GetGladeResourceStream (typeof (GtkPreferenceWidget).Assembly, "SoundPreferenceWidget.glade"), "widget", this);
			
			_btnPlay.Clicked += btnPlayClicked;
			_btnSelectAll.Clicked += SelectAllClicked;
			_btnSelectNone.Clicked += SelectNoneClicked;
			
			
			_store = new ListStore(typeof (bool), typeof(string), typeof (object));
			_tvSounds.Model = _store;
			
			CellRendererToggle toggleRenderer = new CellRendererToggle ();
			toggleRenderer.Activatable = true;
			toggleRenderer.Toggled += new ToggledHandler (EnabledToggled);
			
			CellRendererText nameRenderer = new CellRendererText ();
			TreeViewColumn nameColumn = new TreeViewColumn();
			nameColumn.Title = GettextCatalog.GetString ("Event");
			nameColumn.PackStart (nameRenderer, true);
			nameColumn.AddAttribute (nameRenderer, "text", 1);
			
			TreeViewColumn toggleColumn = new TreeViewColumn();
			toggleColumn.Title = GettextCatalog.GetString ("Enabled");
			toggleColumn.PackStart (toggleRenderer, true);
			toggleColumn.AddAttribute (toggleRenderer, "active", 0);

			_tvSounds.AppendColumn (toggleColumn);
			_tvSounds.AppendColumn (nameColumn);

			_store.SetSortFunc (1, new TreeIterCompareFunc (SortTextFunc));
			_store.SetSortColumnId (1, SortType.Ascending);

			_cbSets = new ImageComboBox<ISoundSet>(new ImageComboTextLookup<ISoundSet>(SetTextLookup), new ImageComboPixbufLookup<ISoundSet>(SetImageLookup));
			_vbSets.PackStart(_cbSets, false, true, 0);
			
			_noneSet = new AbstractSoundSet("None", string.Empty, string.Empty);
			_cbSets.Append(_noneSet);
			
			foreach (ISoundSet soundSet in SoundSetUtility.Sets)
				_cbSets.Append(soundSet);
			
			_cbSets.Changed += SetChanged;
			
			if (SoundSetUtility.ActiveSet != null)
				_cbSets.Select(SoundSetUtility.ActiveSet);
			else
				_cbSets.Select(_noneSet);
			
			_btnPlay.Sensitive = false;
			_tvSounds.Selection.Changed += TreeViewSelectionChanged;
			
			_nativeWidget.ShowAll ();
		}
		
		private int SortTextFunc (TreeModel model, TreeIter iter1, TreeIter iter2)
		{
			string name1 = model.GetValue (iter1, 1) as string;
			string name2 = model.GetValue (iter2, 1) as string;
		
			if (name1 == null && name2 == null) return 0;
			else if (name1 == null) return -1;
			else if (name2 == null) return 1;

			return name1.CompareTo (name2);
		}
		
		string SetTextLookup (ISoundSet item)
		{
			return item.Name;
		}

		Gdk.Pixbuf SetImageLookup (ISoundSet item, IIconSize size)
		{
			return IconUtility.GetIcon ("galaxium-preferences-themes", size);
		}
		
		void SetChanged (object sender, EventArgs args)
		{
			ISoundSet soundSet = _cbSets.GetSelectedItem();
			
			SoundSetUtility.ActiveSet = soundSet == _noneSet ? null : soundSet;
			
			_lblAuthor.Text = soundSet.Creator;
			_lblDescription.Text = soundSet.Description;
			
			_store.Clear();
			
			if (soundSet != _noneSet)
			{
				foreach (ISound sound in soundSet.Sounds)
					_store.AppendValues (sound.Enabled, sound.Sound.ToString(), sound);
			}
		}
		
		private void btnPlayClicked (object sender, EventArgs args)
		{
			TreeIter iter;
			if (!_tvSounds.Selection.GetSelected (out iter))
			 	return;
			
			ISound sound = _store.GetValue (iter, 2) as ISound;
			SoundUtility.Play (sound.Filename);
		}
		
		public Widget NativeWidget
		{
			get { return _nativeWidget; }
		}
		
		private void TreeViewSelectionChanged (object sender, EventArgs args)
		{
			TreeIter iter;
			_btnPlay.Sensitive = _tvSounds.Selection.GetSelected (out iter);
		}
		
		private void SelectAllClicked (object sender, EventArgs args)
		{
			ChangeEnabledStates (true);
		}
		
		private void SelectNoneClicked (object sender, EventArgs args)
		{
			ChangeEnabledStates (false);
		}
		
		private void EnabledToggled (object sender, ToggledArgs args)
		{
	 		TreeIter iter;
			if (_store.GetIterFromString (out iter, args.Path)) {
	 			bool val = (bool) _store.GetValue (iter, 0);
	 			_store.SetValue (iter, 0, !val);
				
				ISound sound = _store.GetValue (iter, 2) as ISound;
				sound.Enabled = !val;
				
				ISoundSet soundSet = _cbSets.GetSelectedItem();
				if (soundSet != null)
					SoundSetUtility.SaveSoundSetEnabledStates (soundSet);
	 		}
		}
		
		private void ChangeEnabledStates (bool enabled)
		{
			TreeIter iter;
			if (_store.GetIterFirst (out iter)) {
				do {
					ISound sound = _store.GetValue (iter, 2) as ISound;
					sound.Enabled = enabled;

					_store.SetValue (iter, 0, enabled);
				} while (_store.IterNext (ref iter));
			}
			
			ISoundSet soundSet = _cbSets.GetSelectedItem();
			if (soundSet != null)
				SoundSetUtility.SaveSoundSetEnabledStates (soundSet);
		}
	}
}
